package com.zhou.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;

import javax.annotation.Resource;
import java.util.Collections;

public class lock{

    public static void main(String[] args) {
        TryLock tryLock = new TryLock();
        tryLock.trylock("abc","123",3000);

        UnLock unLock = new UnLock();
        unLock.releaseLock("abc","123");
    }
}


/**
 * 上锁
 */
class TryLock {
    @Resource
    private StringRedisTemplate redisTemplate = new StringRedisTemplate();
    public Boolean trylock(String lockKey,String clientId,int time) {
        return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> {
            Jedis jedis = (Jedis) redisConnection.getNativeConnection();
            String result = jedis.set(lockKey, clientId, SetParams.setParams().nx().ex(time));
            if ("OK".equals(result)) {
                System.out.println("上锁成功" + clientId);
                return true;
            }
            System.out.println("上锁失败" + clientId);
            return false;
        });
    }
}

class UnLock {
    /**
     * 与 tryLock 相对应，用作释放锁
     *
     * @param lockKey
     * @param clientId
     * @return
     */
    @Autowired
    private StringRedisTemplate redisTemplate;
    private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    private static final Long RELEASE_SUCCESS = 1L;
    public boolean releaseLock(String lockKey, String clientId) {
        return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> {
            Jedis jedis = (Jedis) redisConnection.getNativeConnection();
            Object result = jedis.eval(RELEASE_LOCK_SCRIPT, Collections.singletonList(lockKey),
                    Collections.singletonList(clientId));
            if (RELEASE_SUCCESS.equals(result)) {
                System.out.println("解锁成功" + clientId);
                return true;
            }
            System.out.println("解锁失败" + clientId);
            return false;
        });
    }
}
